package tc.common.display;

import java.awt.BasicStroke;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.geom.Point2D;

import javax.swing.UIManager;

import tc.common.symbology.SfeatLine;
import tc.common.symbology.Style;
import tc.common.symbology.Symbol;
import tc.common.utility.TcDisplayTransf;
import tc.common.utility.TcDisplayXY;
import tc.common.utility.Vector2D;

public class GentityConnector extends Gentity{
	
	public String text1 = "";
	public String text2 = "";
	
	private GentityText gentityText1;
	private GentityText gentityText2;

	static public Font fontLink;
	
	static {
		fontLink = UIManager.getFont("Panel.font");
		fontLink = new Font(fontLink.getName(), Font.ITALIC, 11);
	}	
	
	public GentityConnector(GentityText gentityText1, GentityText gentityText2) {
		this.gentityText1 = gentityText1;
		this.gentityText2 = gentityText2;
	}
	
	@Override
	public void display(Graphics g, TcDisplayTransf transf) {
		/*if ( (gentityText1 == null) || (gentityText2 == null) ) {
			return;
		}*/
		
		TcDisplayXY XY1 = new TcDisplayXY(gentityText1.position, transf, TcDisplayXY.CoordSys.WORLD);
		XY1.transform(TcDisplayXY.CoordSys.DEVICE);
		
		TcDisplayXY XY2 = new TcDisplayXY(gentityText2.position, transf, TcDisplayXY.CoordSys.WORLD);
		XY2.transform(TcDisplayXY.CoordSys.DEVICE);
		
		GentityText.ObjectRectangle rect1 = gentityText1.getObjectRectangle(g, XY1.xy);
		GentityText.ObjectRectangle rect2 = gentityText2.getObjectRectangle(g, XY2.xy);
		
		//g.drawLine((int)XY1.xy.x, (int)XY1.xy.y, (int)XY2.xy.x, (int)XY2.xy.y);
		displayLink(g, XY1.xy, XY2.xy, rect1, rect2);
		
		if ( style == styleDefault ) return; 
		displayLinkStyled(g, style, XY1.xy, XY2.xy, rect1, rect2);
	}
	
	private void displayLink(Graphics g, Point2D.Double xy1, Point2D.Double xy2, GentityText.ObjectRectangle r1, GentityText.ObjectRectangle r2) {
		displayLinkShorten(r1, r2, xy1, xy2);
		displayLinkShorten(r2, r1, xy2, xy1);
	
		if (style == styleDefault) {
			g.drawLine((int) xy1.x, (int) xy1.y, (int) xy2.x, (int) xy2.y);
		}

		Vector2D dir = new Vector2D(xy1, xy2);

		Font oldf = g.getFont();
		g.setFont(GentityConnector.fontLink);

		dir.multiply(0.33333);

		Point2D.Double p0 = new Point2D.Double(xy1.x, xy1.y);
		dir.addTo(p0);

		Point2D.Double p1 = new Point2D.Double(xy1.x, xy1.y);
		dir.multiply(2.0);
		dir.addTo(p1);

		g.drawString(text1, (int)p0.x, (int)p0.y);
		g.drawString(text2, (int)p1.x, (int)p1.y);

		g.setFont(oldf);
	}
	
	private void displayLinkStyled(Graphics g, Style style, Point2D.Double xy1, Point2D.Double xy2, GentityText.ObjectRectangle r1, GentityText.ObjectRectangle r2) {
		displayLinkShorten(r1, r2, xy1, xy2);
		displayLinkShorten(r2, r1, xy2, xy1);
		
		Graphics2D g2 = (Graphics2D)g;
		Stroke oldStroke = g2.getStroke();
		g2.setStroke(new BasicStroke(2.0F));
		
		g2.drawLine((int) xy1.x, (int) xy1.y, (int) xy2.x, (int) xy2.y);
		
		for (int i = 0; i < style.sfeats.size(); i++ ) {
			SfeatLine sfLine = style.sfeats.get(i).getAsLine();
			if (sfLine == null) continue;
			
			if (sfLine.symbolBegin != null) {
				sfLine.symbolBegin.displayRot(g, (int)xy1.x, (int)xy1.y, -12, 0, 
						Symbol.DIM*2/24, Symbol.DIM*2/24, (int)(xy2.x-xy1.x), (int)(xy2.y-xy1.y));
			}
			
			if (sfLine.symbolEnd != null) {
				sfLine.symbolEnd.displayRot(g, (int)xy2.x, (int)xy2.y, 12, 0, 
						Symbol.DIM*2/24, Symbol.DIM*2/24, (int)(xy2.x-xy1.x), (int)(xy2.y-xy1.y));
			}
		}

		g2.setStroke(oldStroke);
	}
	
	private boolean displayLinkShortenDecision(int d0, int d1, int d2, int d3) {
		if (d0 < d1) return false;
		if (d0 < d2) return false;
		if (d0 < d3) return false;
		return true;
	}
	
	private void displayLinkShorten(GentityText.ObjectRectangle r, GentityText.ObjectRectangle r2, Point2D.Double xy, Point2D.Double xy2) {
		int left  = r.x - (r2.x+r2.width);
		int right = r2.x - (r.x+r.width); 
		
		int up  = r.y - (r2.y+r2.height);
		int down = r2.y - (r.y+r.height);
		
		up -= up/3;
		down -= down/3;
		
		if (displayLinkShortenDecision(left, right, up, down) ) {
			xy.x = r.x-r.offset;
		}
		else if (displayLinkShortenDecision(right, left, up, down) ) {
			xy.x = r.x+r.width+r.offset;
		}
		else if (displayLinkShortenDecision(up, left, right, down) ) {
			xy.y = r.y-r.offset;
		}
		else {
			xy.y = r.y+r.height+r.offset;
		}
	}
}
